package utilities;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.awt.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import p2pExceptions.FileUnwritableException;
import p2pExceptions.NoBufferedWriterException;
import p2pExceptions.NoFileException;
import java.awt.Color;

/**
 *
 * @author hz
 */
public class WriteFile {

    public WriteFile() {
        file = null;
        fstream = null;
        bstream = null;
        fileOpen = false;
        readyForWrite = false;
        savedMoves = 0;
    }

    public WriteFile(String path) {
        try {
            file = new File(path + ".chs");
            if (!file.exists()) {
                file.createNewFile();
            }
            fstream = new FileWriter(file);
            bstream = new BufferedWriter(fstream);
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
        }
        fileOpen = true;
        readyForWrite = true;
    }

    public WriteFile(File f) {
        try {
            file = f;
            if (!file.exists()) {
                file.createNewFile();
            }
            fstream = new FileWriter(file);
            bstream = new BufferedWriter(fstream);
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
        }
        fileOpen = true;
        readyForWrite = true;
    }

    public void close() throws IOException {
        try {
            bstream.close();
            fstream.close();
            bstream = null;
            fstream = null;
            file = null;
            fileOpen = false;
            readyForWrite = false;
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }
    }

    public boolean open(File f) throws FileUnwritableException, IOException {
        try {
            file = f;
            if (!file.exists()) {
                file.createNewFile();
            }
            if (!file.canWrite()) {
                file = null;
                throw new FileUnwritableException();
            }
            fstream = new FileWriter(file);
            bstream = new BufferedWriter(fstream);
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
            file = null;
            throw ex;
        }
        fileOpen = true;
        readyForWrite = true;
        return true;
    }

    public boolean open(String path) throws IOException, FileUnwritableException {
        try {
            file = new File(path);
            if (!file.exists()) {
                file.createNewFile();
            }
            if (!file.canWrite()) {
                file = null;
                throw new FileUnwritableException();
            }
            fstream = new FileWriter(file);
            bstream = new BufferedWriter(fstream);
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
            file = null;
            throw ex;
        }
        fileOpen = true;
        readyForWrite = true;
        return true;
    }

    public String getFileName() {
        return file.getName();
    }

    public File getFile() throws NoFileException {
        if (file == null) {
            throw new NoFileException();
        }
        return file;
    }

    public boolean isFileOpen() {
        return fileOpen;
    }

    public boolean isReadyForWrite() {
        return readyForWrite && file.canWrite();
    }

    public BufferedWriter getBufferedWriter() throws NoBufferedWriterException {
        if (bstream == null) {
            throw new NoBufferedWriterException();
        }
        return bstream;
    }

    public void write(List list, String Hash, Color color) {
        try {
            StringBuilder s = new StringBuilder();
            String clr;
            if(color == Color.BLACK){ clr = "BLACK";}
            else clr = "WHITE";
            if (file != null && file.canWrite()) {
                System.err.println(list.getItemCount());
                for (int i = savedMoves; i < list.getItemCount(); i++) {                   
                    s.append(list.getItem(i).toString());
                    s.append('\n');
                    s.append(clr);
                    s.append('\n');
                }
                s.append(Hash); //put hash value at the end of the file
                s.append('\n');
                savedMoves = list.getItemCount()-1;

                bstream.write(s.toString());
                bstream.flush();

            }
        }
        catch (IOException e) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, e);
        }
    }

    public boolean write(String str) throws IOException, FileUnwritableException {
        try {
            if (!isReadyForWrite()) {
               throw new FileUnwritableException();
            }
            bstream.write(str);
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }
        return true;
    }

    public boolean write(int i) throws IOException, FileUnwritableException {
        try {
            if (!isReadyForWrite()) {
                throw new FileUnwritableException();
            }
            bstream.write(i);
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }
        return true;
    }

    public boolean write(char[] str) throws IOException, FileUnwritableException {
        try {
            if (!isReadyForWrite()) {
                throw new FileUnwritableException();
            }
            bstream.write(str);
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }
        return true;
    }

    public boolean newLine() throws FileUnwritableException, IOException {
        try {
            if (!isReadyForWrite()) {
                throw new FileUnwritableException();
            }
            bstream.newLine();
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }
        return true;
    }

    public boolean append(String str) throws IOException, FileUnwritableException {
        try {
            if (!isReadyForWrite()) {
                throw new FileUnwritableException();
            }
            bstream.append(str);
        } catch (IOException ex) {
            Logger.getLogger(WriteFile.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }
        return true;
    }
    private BufferedWriter bstream;
    private FileWriter fstream;
    private File file;
    private boolean fileOpen = false;
    private boolean readyForWrite = false;
    private int savedMoves;
}